page.tsx 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. 'use client';
  2. import './style.scss';
  3. import { useState, useEffect } from 'react';
  4. import { useParams } from 'next/navigation';
  5. import { fetchApi } from '@/lib/utils/client';
  6. type ConsentInfo = {
  7. crewSessionID: number;
  8. title: string;
  9. crewName: string;
  10. isConsented: boolean;
  11. crewMemberID: number;
  12. };
  13. export default function CrewConsentPage()
  14. {
  15. const { sessionID } = useParams<{ sessionID: string }>();
  16. const [info, setInfo] = useState<ConsentInfo|null>(null);
  17. const [loading, setLoading] = useState(true);
  18. const [agreed, setAgreed] = useState(false);
  19. const [submitting, setSubmitting] = useState(false);
  20. const [done, setDone] = useState(false);
  21. useEffect(() => {
  22. fetchApi<ConsentInfo>(`/api/crew/consent/info/${sessionID}`)
  23. .then(res => {
  24. const data = res.data;
  25. setInfo(data ?? null);
  26. if (data?.isConsented) setDone(true);
  27. })
  28. .catch(() => {})
  29. .finally(() => setLoading(false));
  30. }, [sessionID]);
  31. const handleConsent = async () => {
  32. if (!info || !agreed) return;
  33. setSubmitting(true);
  34. try {
  35. await fetchApi('/api/crew/session/consent', {
  36. method: 'POST',
  37. body: {
  38. crewSessionID: info.crewSessionID,
  39. crewMemberID: info.crewMemberID
  40. }
  41. });
  42. setDone(true);
  43. } catch (err: unknown) {
  44. alert(err instanceof Error ? err.message : '동의 처리에 실패했습니다.');
  45. } finally {
  46. setSubmitting(false);
  47. }
  48. };
  49. if (loading) return <div className="crew-consent"><p>준비 중...</p></div>;
  50. if (!info) return <div className="crew-consent"><p>세션 정보를 찾을 수 없습니다.</p></div>;
  51. return (
  52. <div className="crew-consent">
  53. <h1 className="crew-consent__title">크루 방송 참여 동의</h1>
  54. <p className="crew-consent__subtitle">크루장이 방송 참여를 요청했습니다</p>
  55. <div className="crew-consent__info">
  56. <div className="crew-consent__row">
  57. <span className="crew-consent__row-label">크루</span>
  58. <span className="crew-consent__row-value">{info.crewName}</span>
  59. </div>
  60. <div className="crew-consent__row">
  61. <span className="crew-consent__row-label">방송 제목</span>
  62. <span className="crew-consent__row-value">{info.title}</span>
  63. </div>
  64. </div>
  65. {done ? (
  66. <div className="crew-consent__done">✓ 동의가 완료되었습니다. 전원 동의 시 방송이 시작됩니다.</div>
  67. ) : (
  68. <>
  69. <div className="crew-consent__check">
  70. <input type="checkbox" id="agree" checked={agreed} onChange={e => setAgreed(e.target.checked)} />
  71. <label htmlFor="agree">크루 방송 참여에 동의합니다</label>
  72. </div>
  73. <button
  74. type="button"
  75. className="studio-page__btn studio-page__btn--primary"
  76. onClick={handleConsent}
  77. disabled={!agreed || submitting}
  78. >
  79. {submitting ? '처리 중...' : '동의하기'}
  80. </button>
  81. </>
  82. )}
  83. </div>
  84. );
  85. }